import React, { memo, useContext, useEffect, useState } from "react";
import { NsTreeContext, NsTreeContextData } from "@pkgs/Layout/Provider";
import AreaItem from "./AreaItem";
import BarItem from "./BarItem";
import Detection from "./Detection";
import { getCapacity } from "@common/envOverviewApi/search";
import { data2json, replaceObjectKey } from "../utils";
import request from "@pkgs/request";
import { message } from "antd";
import api from "@common/api";
import "./style.less";

interface AreaObject {
  height?: number;
  color?: string;
  smooth?: boolean;
  xField: string;
  yField: string;
  xAxis?: boolean;
  yAxis?: any;
  seriesField?: string;
  areaStyle?: {
    fill?: string;
  };
  point?: any;
}

interface BarObject {
  xField: string;
  yField: string;
  height?: number;
  seriesField?: string;
  color?: string;
  legend?: {
    position?: string;
  };
}

interface ConsistencyType {
  environment_consistency: number;
  environment_failnum: number;
  environment_succrate: number;
  service_consistency: number;
  service_failnum: number;
  service_succrate: number;
  sla: number;
  total: number;
}

type Props = {
  keywords?: string;
};

/**
 * @func 环境总览页面组件
 * @param props
 * @returns React.FC
 */
const Improved: React.FC<Props> = (props) => {
  const [data, setData] = useState<ConsistencyType>({
    environment_consistency: 0,
    environment_failnum: 0,
    environment_succrate: 0,
    service_consistency: 0,
    service_failnum: 0,
    service_succrate: 0,
    sla: 0,
    total: 0,
  });
  const [barData, setBarData] = useState<Record<string, any>[]>([]);
  const [envConsistency, setEnvConsistency] = useState<any>([]);
  const [envSuccrate, setEnvSuccrate] = useState<any>([]);
  const [serConsistency, setSerConsistency] = useState<any>([]);
  const [serSuccrate, setSerSuccrate] = useState<any>([]);
  const [sla, setSla] = useState<any>([]);
  // HACK 这里的 node节点如果使用 props 中传过来的会在路由切换时丢失节点信息，暂时直接从全局的上下文中获取
  let { keywords } = props;
  const context: NsTreeContextData = useContext(NsTreeContext);

  const { selectedNode } = context.data;
  keywords = keywords ? keywords : selectedNode?.path;

  useEffect(() => {
    if (keywords) {
      asyncFetch();
      barFetch();
      areaFetch();
    }
  }, [keywords]);

  /**
   * NOTE 环境 SLA 信息请求
   */
  const asyncFetch = () => {
    request(`${api.consistency}/${keywords}`)
      .then((response) => {
        setData(response);
      })
      .catch((err) => {
        setData({
          environment_consistency: 0,
          environment_failnum: 0,
          environment_succrate: 0,
          service_consistency: 0,
          service_failnum: 0,
          service_succrate: 0,
          sla: 0,
          total: 0,
        });
      });
  };

  /**
   * NOTE 一致性评分历史曲线数据
   */
  const areaFetch = () => {
    request(`${api.consistencyhistory}/${keywords}`)
      .then((response) => {
        const {
          environment_consistency,
          environment_succrate,
          service_consistency,
          service_sla,
          service_succrate,
        } = response;
        setEnvConsistency(
          replaceObjectKey(environment_consistency, "环境一致性")
        );
        setEnvSuccrate(
          replaceObjectKey(environment_succrate, "环境检查成功率")
        );
        setSerConsistency(replaceObjectKey(service_consistency, "服务一致性"));
        setSla(replaceObjectKey(service_sla, "服务SLA分"));
        setSerSuccrate(replaceObjectKey(service_succrate, "服务检查成功率"));
      })
      .catch((err) => {
        message.error("该节点下无一致性评分数据！！！");
        setEnvConsistency([]);
        setEnvSuccrate([]);
        setSerConsistency([]);
        setSla([]);
        setSerSuccrate([]);
      });
  };

  /**
   * @func 容量情况信息请求
   */
  const barFetch = async () => {
    try {
      const data = await getCapacity(keywords || "");
      const { aggregations } = data;
      const json: Record<string, any>[] = data2json(aggregations);
      setBarData(json);
    } catch (err) {}
  };

  const areaConfig: AreaObject = {
    xField: "date",
    yField: "scales",
    yAxis: {
      label: {
        // 数值格式化为百分位
        formatter: (v: number) => `${(v * 100).toFixed()}%`,
      },
    },
    seriesField: "item",
    // 开启辅助点
    point: {
      size: 2,
    },
  };

  const slaAreaConfig: AreaObject = {
    xField: "date",
    yField: "scales",
    yAxis: {
      label: {
        // 数值格式化
        formatter: (v: number) => `${v}分`,
      },
    },
    seriesField: "item",
    // 开启辅助点
    point: {
      size: 2,
    },
  };

  const barConfig: BarObject = {
    xField: "value",
    yField: "key",
    height: 158,
    color: "#a8ddb5",
    legend: {
      position: "top-left",
    },
  };

  return (
    <div>
      <div className="chart">
        <AreaItem
          areaConfig={slaAreaConfig}
          data={sla}
          title={[
            {
              title: "环境SLA",
              prompt: "环境SLA计算规则 服务健康度与环境健康度的平均值",
            },
          ]}
          aggregations={[
            `${typeof data.sla == "number" ? data.sla.toFixed() : "0"}分`,
          ]}
        >
          <div className="sla-info">
            <div>
              机器总数：
              {data.total !== undefined && data.total !== null
                ? data.total
                : "null"}
            </div>
            <div>
              系统检查失败数：
              {data.environment_failnum !== undefined &&
              data.environment_failnum !== null
                ? data.environment_failnum
                : "null"}
            </div>
            <div>
              服务检查失败数：
              {data.service_failnum !== undefined &&
              data.service_failnum !== null
                ? data.service_failnum
                : "null"}
            </div>
          </div>
        </AreaItem>
        <AreaItem
          areaConfig={areaConfig}
          data={[...envConsistency, ...envSuccrate]}
          title={[
            {
              title: "环境一致性",
              prompt: "环境一致性代表上述2项检测结果的一致性比率",
            },
            {
              title: "环境健康度",
              prompt: "环境健康度代表 系统环境监测 或 自定义检测 的成功率",
            },
          ]}
          aggregations={[
            `${
              typeof data.environment_consistency == "number"
                ? (data.environment_consistency * 100).toFixed()
                : "0"
            }%`,
            `${
              typeof data.environment_succrate == "number"
                ? (data.environment_succrate * 100).toFixed()
                : "0"
            }%`,
          ]}
        />
        <AreaItem
          areaConfig={areaConfig}
          data={[...serConsistency, ...serSuccrate]}
          title={[
            {
              title: "服务一致性",
              prompt: "服务一致性代表 应用状态 检查的一致性比率",
            },
            {
              title: "服务健康度",
              prompt: "服务健康度代表 应用状态 检查成功率",
            },
          ]}
          aggregations={[
            `${
              typeof data.service_consistency == "number"
                ? (data.service_consistency * 100).toFixed()
                : "0"
            }%`,
            `${
              typeof data.service_succrate == "number"
                ? (data.service_succrate * 100).toFixed()
                : "0"
            }%`,
          ]}
        />
        <BarItem
          barConfig={barConfig}
          data={barData}
          title={{
            title: "容量情况",
            prompt:
              "容量情况代表节点下机器容量峰值的80分位，方便用户感受整体容量情况",
          }}
        />
      </div>
      <Detection keywords={keywords || ""} />
    </div>
  );
};

export default memo(Improved);
